home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / cctools / as / symbols.c < prev    next >
C/C++ Source or Header  |  1994-03-22  |  14KB  |  504 lines

  1. /* symbols.c -symbol table-
  2.    Copyright (C) 1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "as.h"
  23. #include "hash.h"
  24. #include "obstack.h"        /* For "symbols.h" */
  25. #include "struc-symbol.h"
  26. #include "symbols.h"
  27. #include "frags.h"
  28. #include "expr.h"
  29. #include "sections.h"
  30. #include "read.h"
  31. #include "xmalloc.h"
  32. #include "messages.h"
  33. #include "fixes.h"
  34. #include "input-scrub.h"
  35.  
  36. /* symbol-name => struct symbol pointer */
  37. struct hash_control *sy_hash = NULL;
  38.  
  39. /* FixS & symbols live here */
  40. struct obstack notes = { 0 };
  41.  
  42. /* all the symbol nodes */
  43. symbolS *symbol_rootP = NULL;
  44. /* last struct symbol we made, or NULL */
  45. symbolS *symbol_lastP = NULL;
  46.  
  47. symbolS    abs_symbol = { 0 };
  48.  
  49. /*
  50.  * Un*x idea of local labels. They are made by "n:" where n
  51.  * is any decimal digit. Refer to them with
  52.  *  "nb" for previous (backward) n:
  53.  *  or "nf" for next (forward) n:.
  54.  *
  55.  * Like Un*x AS, we have one set of local label counters for entire assembly,
  56.  * not one set per (sub)segment like in most assemblers. This implies that
  57.  * one can refer to a label in another segment, and indeed some crufty
  58.  * compilers have done just that.
  59.  *
  60.  * I document the symbol names here to save duplicating words elsewhere.
  61.  * The mth occurence of label n: is turned into the symbol "Ln^Am" where
  62.  * n is a digit and m is a decimal number. "L" makes it a label discarded
  63.  * unless debugging and "^A"('\1') ensures no ordinary symbol SHOULD get the
  64.  * same name as a local label symbol. The first "4:" is "L4^A1" - the m
  65.  * numbers begin at 1.
  66.  */
  67.  
  68. typedef short unsigned int local_label_countT;
  69.  
  70. static local_label_countT local_label_counter[10];
  71.  
  72. static                /* Returned to caller, then copied. */
  73.   char symbol_name_build[12];    /* used for created names ("4f") */
  74.  
  75. static void make_stab_for_symbol(
  76.     symbolS *symbolP);
  77.  
  78.  
  79. void
  80. symbol_begin(
  81. void)
  82. {
  83.   symbol_lastP = NULL;
  84.   symbol_rootP = NULL;        /* In case we have 0 symbols (!!) */
  85.   sy_hash = hash_new();
  86.   memset((char *)(&abs_symbol), '\0', sizeof(abs_symbol));
  87.   abs_symbol.sy_type = N_ABS;    /* Can't initialise a union. Sigh. */
  88.   memset((char *)(local_label_counter), '\0', sizeof(local_label_counter) );
  89. }
  90.  
  91. /*
  92.  *            local_label_name()
  93.  *
  94.  * Caller must copy returned name: we re-use the area for the next name.
  95.  */
  96. char *                /* Return local label name. */
  97. local_label_name(
  98. int n,        /* we just saw "n:", "nf" or "nb" : n a digit */
  99. int augend)    /* 0 for nb, 1 for n:, nf */
  100. {
  101.   register char *    p;
  102.   register char *    q;
  103.   char symbol_name_temporary[10]; /* build up a number, BACKWARDS */
  104.  
  105.   know( n >= 0 );
  106.   know( augend == 0 || augend == 1 );
  107.   p = symbol_name_build;
  108.   * p ++ = 'L';
  109.   * p ++ = n + '0';        /* Make into ASCII */
  110.   * p ++ = 1;            /* ^A */
  111.   n = local_label_counter [ n ] + augend;
  112.                 /* version number of this local label */
  113.   /*
  114.    * Next code just does sprintf( {}, "%d", n);
  115.    * It is more elegant to do the next part recursively, but a procedure
  116.    * call for each digit emitted is considered too costly.
  117.    */
  118.   q = symbol_name_temporary;
  119.   for (*q++=0; n; q++)        /* emits NOTHING if n starts as 0 */
  120.     {
  121.       know(n>0);        /* We expect n > 0 always */
  122.       *q = n % 10 + '0';
  123.       n /= 10;
  124.     }
  125.   while (( * p ++ = * -- q ))
  126.     {
  127.     }
  128.   /* The label, as a '\0' ended string, starts at symbol_name_build. */
  129.   return (symbol_name_build);
  130. }
  131.  
  132. void
  133. local_colon(
  134. int n)    /* just saw "n:" */
  135. {
  136.   local_label_counter [n] ++;
  137.   colon (local_label_name (n, 0));
  138. }
  139.  
  140. /*
  141.  *            symbol_new()
  142.  *
  143.  * Return a pointer to a new symbol.
  144.  * Die if we can't make a new symbol.
  145.  * Fill in the symbol's values.
  146.  * Add symbol to end of symbol chain.
  147.  *
  148.  *
  149.  * Please always call this to create a new symbol.
  150.  *
  151.  * Changes since 1985: Symbol names may not contain '\0'. Sigh.
  152.  */
  153. symbolS *
  154. symbol_new(
  155. char           *name,    /* We copy this: OK to alter your copy. */
  156. unsigned char    type,    /* As in <nlist.h>. */
  157. char        other,    /* As in <nlist.h>. */
  158. short        desc,    /* As in <nlist.h>. */
  159. valueT        value,    /* As in <nlist.h>, often an address. */
  160.             /* Often used as offset from frag address. */
  161. struct frag    *frag)    /* For sy_frag. */
  162. {
  163.   register symbolS *        symbolP;
  164.   register char *        preserved_copy_of_name;
  165.   register unsigned int        name_length;
  166.            char *        p;
  167.  
  168.   name_length = strlen(name) + 1;
  169.   obstack_grow(¬es,name,name_length);
  170.   p=obstack_finish(¬es);
  171.   /* obstack_1done( ¬es, name, name_length, &p ); */
  172.   preserved_copy_of_name = p;
  173.   p=obstack_alloc(¬es,sizeof(struct symbol));
  174.   /* obstack_1blank( ¬es, sizeof(struct symbol), &p ); */
  175.   symbolP            = (symbolS *) p;
  176.   symbolP -> sy_name        = preserved_copy_of_name;
  177.   symbolP -> sy_type        = type;
  178.   symbolP -> sy_other        = other;
  179.   symbolP -> sy_desc        = desc;
  180.   symbolP -> sy_value        = value;
  181.   symbolP -> sy_frag        = frag;
  182.   symbolP -> sy_next        = NULL;    /* End of chain. */
  183.   symbolP -> sy_forward        = NULL; /* JF */
  184. #ifdef SUSPECT
  185.   symbolP -> sy_name_offset    = ~ 0; /* Impossible offset catches errors. */
  186.   symbolP -> sy_number        = ~ 0; /* Ditto. */
  187. #endif
  188.   /*
  189.    * Link to end of symbol chain.
  190.    */
  191.   if (symbol_lastP)
  192.     {
  193.       symbol_lastP -> sy_next = symbolP;
  194.     }
  195.   else
  196.     {
  197.       symbol_rootP = symbolP;
  198.     }
  199.   symbol_lastP = symbolP;
  200.  
  201.   return (symbolP);
  202. }
  203.  
  204. /*
  205.  *            colon()
  206.  *
  207.  * We have just seen "<name>:".
  208.  * Creates a struct symbol unless it already exists.
  209.  *
  210.  * Gripes if we are redefining a symbol incompatibly (and ignores it).
  211.  *
  212.  */
  213. void
  214. colon(        /* just seen "x:" - rattle symbols & frags */
  215. char *sym_name) /* symbol name, as a cannonical string */
  216.         /* We copy this string: OK to alter later. */
  217. {
  218.   register struct symbol * symbolP; /* symbol we are working with */
  219.  
  220.   if (frchain_now == NULL)
  221.     {
  222.       know(flagseen['n']);
  223.       as_fatal("with -n a section directive must be seen before assembly "
  224.            "can begin");
  225.     }
  226.   if ((symbolP = symbol_table_lookup( sym_name )))
  227.     {
  228.       /*
  229.        *    Now check for undefined symbols
  230.        */
  231.       if ((symbolP -> sy_type & N_TYPE) == N_UNDF)
  232.     {
  233.       if(   symbolP -> sy_other == 0
  234. /* -O causes this not to work */
  235.          && ((symbolP->sy_desc) & (~REFERENCE_TYPE)) == 0
  236.          && symbolP -> sy_value == 0)
  237.         {
  238.           symbolP -> sy_frag  = frag_now;
  239.           symbolP -> sy_value = obstack_next_free(& frags) - frag_now -> fr_literal;
  240.           know( N_UNDF == 0 );
  241.           symbolP -> sy_type |= N_SECT; /* keep N_EXT bit */
  242.           symbolP -> sy_other = frchain_now->frch_nsect;
  243.           symbolP -> sy_desc &= ~REFERENCE_TYPE;
  244. #ifdef NeXT    /* generate stabs for debugging assembly code */
  245.           if(flagseen['g'])
  246.           make_stab_for_symbol(symbolP);
  247. #endif
  248.         }
  249.       else
  250.         {
  251.           as_fatal( "Symbol \"%s\" is already defined as \"%s\"/%d.%d.%ld.",
  252.               sym_name,
  253.               seg_name [(int) N_TYPE_seg [symbolP -> sy_type & N_TYPE]],
  254.               symbolP -> sy_other, symbolP -> sy_desc,
  255.               symbolP -> sy_value);
  256.         }
  257.     }
  258.       else
  259.     {
  260.       as_fatal("Symbol %s already defined.",sym_name);
  261.     }
  262.     }
  263.   else
  264.     {
  265.       symbolP = symbol_new (sym_name,
  266.                 N_SECT,
  267.                       frchain_now->frch_nsect,
  268.                 0,
  269.                 (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
  270.                 frag_now);
  271.       symbol_table_insert (symbolP);
  272. #ifdef NeXT    /* generate stabs for debugging assembly code */
  273.       if(flagseen['g'])
  274.       make_stab_for_symbol(symbolP);
  275. #endif
  276.     }
  277. }
  278.  
  279.  
  280. /*
  281.  *            symbol_table_insert()
  282.  *
  283.  * Die if we can't insert the symbol.
  284.  *
  285.  */
  286. void
  287. symbol_table_insert(
  288. struct symbol *symbolP)
  289. {
  290.   register char *    error_string;
  291.  
  292.   know( symbolP );
  293.   know( symbolP -> sy_name );
  294.   if ( * (error_string = hash_jam (sy_hash, symbolP -> sy_name, (char *)symbolP)))
  295.     {
  296.       as_fatal( "Inserting \"%s\" into symbol table failed: %s",
  297.           symbolP -> sy_name, error_string);
  298.     }
  299. }
  300.  
  301. /*
  302.  *            symbol_find_or_make()
  303.  *
  304.  * If a symbol name does not exist, create it as undefined, and insert
  305.  * it into the symbol table. Return a pointer to it.
  306.  */
  307. symbolS *
  308. symbol_find_or_make(
  309. char *name)
  310. {
  311.   register symbolS *    symbolP;
  312.  
  313.   symbolP = symbol_table_lookup (name);
  314.   if (symbolP == NULL)
  315.     {
  316.       symbolP = symbol_new (name, N_UNDF, 0, 0, 0, & zero_address_frag);
  317.       symbol_table_insert (symbolP);
  318.     }
  319.   return (symbolP);
  320. }
  321.  
  322. /*
  323.  *            symbol_find()
  324.  * 
  325.  * Implement symbol table lookup.
  326.  * In:    A symbol's name as a string: '\0' can't be part of a symbol name.
  327.  * Out:    NULL if the name was not in the symbol table, else the address
  328.  *    of a struct symbol associated with that name.
  329.  */
  330. symbolS *
  331. symbol_find(
  332. char *name)
  333. {
  334.   return ( (symbolS *) hash_find( sy_hash, name ));
  335. }
  336.  
  337. #ifdef NeXT    /* generate stabs for debugging assembly code */
  338. /*
  339.  * make_stab_for_symbol() is called when -g is present for a label that is
  340.  * being defined.  If the label is a text label and in the (__TEXT,__text)
  341.  * section and not a local label create a stab for it.
  342.  * 
  343.  * See the detailed comments about stabs in read_a_source_file() for a
  344.  * description of what is going on here.
  345.  */
  346. static
  347. void
  348. make_stab_for_symbol(
  349. symbolS *symbolP)
  350. {
  351.     symbolS *stab;
  352.     int stabnamelen;
  353.     char *stabname;
  354.  
  355.     if(symbolP->sy_name[0] == 'L')
  356.         return;
  357.     if((symbolP->sy_type & N_TYPE) != N_SECT)
  358.         return;
  359.     if(symbolP->sy_other != text_nsect)
  360.         return;
  361.  
  362.     stabnamelen = strlen(symbolP->sy_name) + sizeof(":f3");
  363.     stabname = xmalloc(stabnamelen);
  364.     strcpy(stabname, symbolP->sy_name);
  365.     if(symbolP->sy_type & N_EXT)
  366.         strcat(stabname, ":F3");
  367.     else
  368.         strcat(stabname, ":f3");
  369.     
  370.     stab = symbol_new(
  371.         stabname,
  372.         36, /* N_FUN */
  373.         text_nsect, /* n_sect */
  374.         logical_input_line, /* n_desc, line number */
  375.         symbolP->sy_value,
  376.         symbolP->sy_frag);
  377.     free(stabname);
  378. }
  379. #endif /* NeXT generate stabs for debugging assembly code */
  380.  
  381. /*
  382.  * indirect_symbol_new()
  383.  *
  384.  * Return a pointer to a new indirect_symbol.
  385.  * Die if we can't make a new indirect_symbol.
  386.  * Fill in the indirect_symbol's values.
  387.  * Add symbol to end of section's indirect symbol chain.
  388.  */
  389. isymbolS *
  390. indirect_symbol_new(
  391. char           *name,      /* We copy this: OK to alter your copy. */
  392. struct frag    *frag,      /* For sy_frag. */
  393. unsigned long    offset)      /* Offset from frag address. */
  394. {
  395.     isymbolS *isymbolP;
  396.     char *preserved_copy_of_name;
  397.     unsigned long name_length;
  398.     char *p;
  399.     struct frag *fr_next;
  400. #ifdef CHECK_INDIRECTS
  401.     unsigned long stride, fr_fix;
  402. #endif
  403.  
  404.     /*
  405.      * First see if the last frag recorded for an indirect symbol turned
  406.      * out to be zero sized then changed that recorded frag to the next
  407.      * non-zero frag in the list.  I think this happens because we record
  408.      * the frag before we fill it and if we run out of space that frag gets
  409.      * a zero size and a new one is created.
  410.      */
  411.     if(frchain_now->frch_isym_last != NULL &&
  412.        frchain_now->frch_isym_last->isy_frag->fr_fix == 0){
  413.         if(frchain_now->frch_isym_last->isy_frag->fr_next != NULL){
  414.         fr_next = frchain_now->frch_isym_last->isy_frag->fr_next;
  415.         while(fr_next->fr_fix == 0 &&
  416.               fr_next->fr_type == rs_fill &&
  417.               fr_next->fr_next != NULL)
  418.             fr_next = fr_next->fr_next;
  419.         frchain_now->frch_isym_last->isy_frag = fr_next;
  420.         }
  421.     }
  422.  
  423.     name_length = strlen(name) + 1;
  424.     obstack_grow(¬es, name, name_length);
  425.     p = obstack_finish(¬es);
  426.     preserved_copy_of_name = p;
  427.     p = obstack_alloc(¬es, sizeof(struct indirect_symbol));
  428.     isymbolP = (isymbolS *)p;
  429.     isymbolP->isy_name    = preserved_copy_of_name;
  430.     isymbolP->isy_offset  = offset;
  431.     isymbolP->isy_frag    = frag;
  432.     isymbolP->isy_next    = NULL;    /* End of chain. */
  433.     isymbolP->isy_symbol  = NULL;
  434.  
  435.     /*
  436.      * Link to end of indirect symbol chain and check for missing indirect
  437.      * symbols.
  438.      */
  439.     if(frchain_now->frch_isym_root == NULL){
  440. #ifdef CHECK_INDIRECTS
  441.         if(offset != 0)
  442.         as_warn("missing or bad indirect symbol for section (%s,%s)",
  443.             frchain_now->frch_section.segname,
  444.             frchain_now->frch_section.sectname);
  445. #endif
  446.         frchain_now->frch_isym_root = isymbolP;
  447.         frchain_now->frch_isym_last = isymbolP;
  448.     }
  449.     else{
  450. #ifdef CHECK_INDIRECTS
  451.         if((frchain_now->frch_section.flags & SECTION_TYPE) ==
  452.            S_SYMBOL_STUBS)
  453.         stride = frchain_now->frch_section.reserved2;
  454.         else
  455.         stride = sizeof(unsigned long);
  456.         if(frag == frchain_now->frch_isym_last->isy_frag){
  457.         if(offset - frchain_now->frch_isym_last->isy_offset != stride)
  458.             as_warn("missing or bad indirect symbol for section "
  459.                 "(%s,%s)", frchain_now->frch_section.segname,
  460.                 frchain_now->frch_section.sectname);
  461.         }
  462.         else{
  463.         if(frchain_now->frch_isym_last->isy_frag->fr_fix < stride){
  464.             fr_fix = 0;
  465.             fr_next = frchain_now->frch_isym_last->isy_frag;
  466.             while(fr_fix + fr_next->fr_fix < stride &&
  467.               fr_next->fr_type == rs_fill &&
  468.               fr_next->fr_next != NULL){
  469.             fr_fix += fr_next->fr_fix;
  470.             fr_next = fr_next->fr_next;
  471.             }
  472.             if(frag != fr_next->fr_next ||
  473.                fr_fix + fr_next->fr_fix != stride ||
  474.                offset != 0)
  475.             as_warn("missing or bad indirect symbol for section "
  476.                 "(%s,%s)", frchain_now->frch_section.segname,
  477.                 frchain_now->frch_section.sectname);
  478.         }
  479.         else{
  480.             fr_next = frchain_now->frch_isym_last->isy_frag->fr_next;
  481.             /*
  482.              * Because of section changes there maybe some zero length
  483.              * frags after the last one that passed through here.  So
  484.              * skip them and get to the last real one.
  485.              */
  486.             while(fr_next->fr_fix == 0 &&
  487.               fr_next->fr_type == rs_fill &&
  488.               fr_next->fr_next != NULL)
  489.             fr_next = fr_next->fr_next;
  490.             if(frag != fr_next || offset != 0)
  491.             as_warn("missing or bad indirect symbol for section "
  492.                 "(%s,%s)", frchain_now->frch_section.segname,
  493.                 frchain_now->frch_section.sectname);
  494.         }
  495.         }
  496. #endif
  497.         frchain_now->frch_isym_last->isy_next = isymbolP;
  498.         frchain_now->frch_isym_last = isymbolP;
  499.     }
  500.     return(isymbolP);
  501. }
  502.  
  503. /* end: symbols.c */
  504.